//
// Created by rm on 2022/3/22.
//

#include "four_points.h"
void DrawRect1(Mat& canvas,RotatedRect object)
{
    Point2f vertexes[4];
    object.points(vertexes);
    for (int i = 0; i < 4; i++)
    {
        line(canvas, vertexes[i],vertexes[(i+1)%4], Scalar(0,0,255), 2);
    }
}
void DrawRect(Mat& canvas,RotatedRect object,RotatedRect object1)
{   Point2f v1[4];
    Point2f v2[4];
    if(object.angle>100&&object1.angle>100){
        Point2f v3[4];
        object.points(v3);
        Point2f v4[4];
        object1.points(v4);
        if(v3[1].x>v4[1].x){
            object.points(v1);
            object1.points(v2);
        }
        else{
            object.points(v2);
            object1.points(v1);
        }
        line(canvas, v1[2],v2[1], Scalar(0,0,255), 2);
        line(canvas, v1[3],v2[0], Scalar(0,0,255), 2);
        line(canvas, v1[3],v1[2], Scalar(0,0,255), 2);
        line(canvas, v2[0],v2[1], Scalar(0,0,255), 2);
        cout<<v1[2]<<" "<<v1[3]<<" "<<v2[0]<<" "<<v2[1]<<endl;
    }
    else if(object.angle<80&&object1.angle<80){
        Point2f v3[4];
        object.points(v3);
        Point2f v4[4];
        object1.points(v4);
        if(v3[3].x>v4[3].x){
            object.points(v1);
            object1.points(v2);
        }
        else{
            object.points(v2);
            object1.points(v1);
        }

        line(canvas, v1[0],v2[3], Scalar(0,0,255), 2);
        line(canvas, v1[1],v2[2], Scalar(0,0,255), 2);
        line(canvas, v1[1],v1[0], Scalar(0,0,255), 2);
        line(canvas, v2[2],v2[3], Scalar(0,0,255), 2);
        cout<<v1[0]<<" "<<v1[1]<<" "<<v2[2]<<" "<<v2[3]<<endl;
    }
    else if(object.angle>100&&object1.angle<80){

        Point2f v3[4];
        object.points(v3);
        Point2f v4[4];
        object1.points(v4);
        if(v3[1].x>v4[3].x){
            object.points(v1);
            object1.points(v2);
            line(canvas, v1[2],v1[3], Scalar(0,0,255), 2);
            line(canvas, v1[3],v2[2], Scalar(0,0,255), 2);
            line(canvas, v2[2],v2[3], Scalar(0,0,255), 2);
            line(canvas, v2[3],v1[2], Scalar(0,0,255), 2);
            cout<<v1[2]<<" "<<v1[3]<<" "<<v2[2]<<" "<<v2[3]<<endl;
        }
        else if(v3[1].x<v4[3].x){
            object.points(v2);
            object1.points(v1);
            line(canvas, v1[0],v1[1], Scalar(0,0,255), 2);
            line(canvas, v1[1],v2[0], Scalar(0,0,255), 2);
            line(canvas, v2[0],v2[1], Scalar(0,0,255), 2);
            line(canvas, v2[1],v1[0], Scalar(0,0,255), 2);
            cout<<v1[0]<<" "<<v1[1]<<" "<<v2[0]<<" "<<v2[1]<<endl;
        }
    }
    else if(object.angle<80&&object1.angle>100){

        Point2f v3[4];
        object.points(v3);
        Point2f v4[4];
        object1.points(v4);
        if(v3[1].x>v4[3].x){
            object.points(v1);
            object1.points(v2);
            line(canvas, v1[0],v1[1], Scalar(0,0,255), 2);
            line(canvas, v1[1],v2[0], Scalar(0,0,255), 2);
            line(canvas, v2[0],v2[1], Scalar(0,0,255), 2);
            line(canvas, v2[1],v1[0], Scalar(0,0,255), 2);
            cout<<v1[0]<<" "<<v1[1]<<" "<<v2[0]<<" "<<v2[1]<<endl;
        }
        else if(v3[1].x<v4[3].x){
            object.points(v2);
            object1.points(v1);
            line(canvas, v1[2],v1[3], Scalar(0,0,255), 2);
            line(canvas, v1[3],v2[2], Scalar(0,0,255), 2);
            line(canvas, v2[2],v2[3], Scalar(0,0,255), 2);
            line(canvas, v2[3],v1[2], Scalar(0,0,255), 2);
            cout<<v1[2]<<" "<<v1[3]<<" "<<v2[2]<<" "<<v2[3]<<endl;

        }
    }

}
Mat Pretreat(Mat& img)
{
    vector<Mat> bgr(3);
    split(img,bgr);
    Mat sub_br;
    subtract(bgr[2],bgr[0],sub_br);
    blur(sub_br, sub_br, Size(4,12));
    threshold(sub_br,sub_br,50,255,1);
//    Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(12, 12));
//    dilate(sub_br, sub_br, element);
    return sub_br;
}
void FixArmor(Mat& img,Mat& img1)
{
    Mat canvas = Mat::zeros(img.size(),CV_8UC1);
    vector<vector<Point>> contour;
    vector<Vec4i> hierarchy;
    vector<RotatedRect > v;
    //RETR_EXTERNAL RETR_TREE  //CHAIN_APPROX_NONE CHAIN_APPROX_SIMPLE
    findContours(img,contour,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));
    for(auto i =0;i<contour.size();i++)
    {

        for(auto j=0;j<contour[i].size();j++)
        {
            circle(canvas,contour[i][j],0.1,Scalar(255));
        }
    }

    for (int i = 0; i < contour.size(); i++)
    {
        double area = contourArea(contour[i]);
        if (area < 10|| area>20000)
            continue;
        RotatedRect rect = fitEllipse(contour[i]);
        if (rect.size.height / rect.size.width > 7
            || area/ rect.size.area() < 0.5||rect.size.height / rect.size.width <1)
            continue;
        DrawRect1(img1,rect);
        v.push_back(rect);
    }
    if(v.size()>1){
        DrawRect(img1,v[0],v[1]);
    }
}

void find_points(Mat frame)
{
    Mat sub_br;
    sub_br=Pretreat(frame);
    FixArmor(sub_br,frame);
    namedWindow("video",0);
    imshow("video", frame);
}